home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / dmake-3.6 / part22 < prev    next >
Encoding:
Text File  |  1990-10-14  |  39.5 KB  |  1,420 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: dvadura@watdragon.waterloo.edu
  3. subject: v15i074: dmake version 3.6 (part 22/25)
  4. from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 74
  8. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  9. Archive-name: dmake-3.6/part22
  10.  
  11. #!/bin/sh
  12. # this is part 22 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file dmake.h continued
  15. #
  16. CurArch=22
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file dmake.h"
  27. sed 's/^X//' << 'SHAR_EOF' >> dmake.h
  28. X#define ST_IMPORT    9
  29. X
  30. X/* Macro definitions for use inside dmake */
  31. X#define SET_TOKEN(A, B)  (A)->tk_str = (B); (A)->tk_cchar = *(B);\
  32. X             (A)->tk_quote = 1;
  33. X#define CLEAR_TOKEN(A)   *(A)->tk_str = (A)->tk_cchar
  34. X#define GET_MACRO(A)     Get_name(A, Macs, FALSE, NIL(CELL))
  35. X#define iswhite(C)     ((C == ' ') || (C == '\t'))
  36. X
  37. X#endif
  38. X
  39. SHAR_EOF
  40. echo "File dmake.h is complete"
  41. chmod 0440 dmake.h || echo "restore of dmake.h fails"
  42. echo "x - extracting dmake.c (Text)"
  43. sed 's/^X//' << 'SHAR_EOF' > dmake.c &&
  44. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.c,v 1.1 90/10/06 12:03:35 dvadura Exp $
  45. X-- SYNOPSIS -- The main program.
  46. X-- 
  47. X-- DESCRIPTION
  48. X-- 
  49. X--     dmake [-#dbug_string] [ options ]
  50. X--             [ macro definitions ] [ target ... ]
  51. X-- 
  52. X--     This file contains the main command line parser for the
  53. X--     make utility.  The valid flags recognized are as follows:
  54. X-- 
  55. X--     -f file         - use file as the makefile
  56. X--     -#dbug_string   - dump out debugging info, see below
  57. X-- 
  58. X--      options: (can be catenated, ie -irn == -i -r -n)
  59. X-- 
  60. X--    -A        - enable AUGMAKE special target mapping
  61. X--     -i              - ignore errors
  62. X--     -n              - trace and print, do not execute commands
  63. X--     -t              - touch, update dates without executing commands
  64. X--     -T              - do not apply transitive closure
  65. X--     -r              - don't use internal rules
  66. X--     -s              - do your work silently
  67. X--    -S        - force Sequential make, overrides -P
  68. X--     -q              - check if target is up to date.  Does not
  69. X--               do anything.  Returns 0 if up to date, -1
  70. X--               otherwise.
  71. X--     -p              - print out a version of the makefile
  72. X--    -P#        - set value of MAXPROCESS
  73. X--     -e              - define environment strings as macros
  74. X--     -E              - as -e but done after parsing makefile
  75. X--     -u              - force unconditional update of target
  76. X--     -k              - make all independent targets even if errors
  77. X--     -V              - print out this make version number
  78. X--     -v        - verbose, print what we are doing, as we do it.
  79. X--     -M        - Microsoft make compatibility, (* disabled *)
  80. X--     -h              - print out usage info
  81. X--     -x        - export macro defs to environment
  82. X-- 
  83. X--     NOTE:  - #ddbug_string is only availabe for versions of dmake that
  84. X--         have been compiled with -DDBUG switch on.  Not the case for
  85. X--         distributed versions.  Any such versions must be linked
  86. X--         together with a version of Fred Fish's debug code.
  87. X--              
  88. X--     NOTE:  - in order to compile the code the include file stddef.h
  89. X--         must be shipped with the bundled code.
  90. X-- 
  91. X-- AUTHOR
  92. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  93. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  94. X--
  95. X-- COPYRIGHT
  96. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  97. X-- 
  98. X--      This program is free software; you can redistribute it and/or
  99. X--      modify it under the terms of the GNU General Public License
  100. X--      (version 1), as published by the Free Software Foundation, and
  101. X--      found in the file 'LICENSE' included with this distribution.
  102. X-- 
  103. X--      This program is distributed in the hope that it will be useful,
  104. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  105. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  106. X--      GNU General Public License for more details.
  107. X-- 
  108. X--      You should have received a copy of the GNU General Public License
  109. X--      along with this program;  if not, write to the Free Software
  110. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  111. X--
  112. X-- LOG
  113. X--     $Log:    dmake.c,v $
  114. X * Revision 1.1  90/10/06  12:03:35  dvadura
  115. X * dmake Release, Version 3.6
  116. X * 
  117. X*/
  118. X
  119. X/* Set this flag to one, and the global variables in vextern.h will not
  120. X * be defined as 'extern', instead they will be defined as global vars
  121. X * when this module is compiled. */
  122. X#define _DEFINE_GLOBALS_ 1
  123. X
  124. X#include <ctype.h>
  125. X#include <stdarg.h>
  126. X#include "extern.h"
  127. X#include "alloc.h"
  128. X#include "db.h"
  129. X#include "patchlvl.h"
  130. X#include "version.h"
  131. X
  132. X#ifdef HELP
  133. X#define USAGE \
  134. X"Usage:\n%s [-AeEhiknpqrsStTuvVx] [-P#] [-f file] [macro[*][+][:]=value ...] [target ...]\n"
  135. X#define COPYRIGHT "Copyright (c) 1990 by Dennis Vadura"
  136. X#endif
  137. X
  138. Xstatic char *sccid = COPYRIGHT;
  139. Xstatic char _warn  = TRUE;        /* warnings on by default */
  140. X
  141. Xstatic    void    _do_VPATH();
  142. Xstatic    void    _do_ReadEnvironment();
  143. X
  144. Xmain(argc, argv)
  145. Xint  argc;
  146. Xchar **argv;
  147. X{
  148. X   char*   fil_name = NIL(char);
  149. X   char*   cmdmacs;
  150. X   char*   targets;
  151. X   FILE*   mkfil;
  152. X   int     ex_val;
  153. X   int     m_export;
  154. X   HASHPTR hp;
  155. X
  156. X   DB_ENTER("main");
  157. X
  158. X   /* Initialize Global variables to their default values       */
  159. X   Prolog(argc, argv);
  160. X   Create_macro_vars();
  161. X   Catch_signals(Quit);
  162. X
  163. X   Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT );
  164. X   Pname = basename(Pname);
  165. X
  166. X   DB_PROCESS(Pname);
  167. X   (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
  168. X
  169. X   Continue  = FALSE;
  170. X   Get_env   = FALSE;
  171. X   Force     = FALSE;
  172. X   Target    = FALSE;
  173. X   If_expand = FALSE;
  174. X   Listing   = FALSE;
  175. X   Readenv   = FALSE;
  176. X   Rules     = TRUE;
  177. X   Trace     = FALSE;
  178. X   Touch     = FALSE;
  179. X   Check     = FALSE;
  180. X   Microsoft = FALSE;
  181. X   Verbose   = FALSE;
  182. X   Makemkf   = FALSE;
  183. X   m_export  = FALSE;
  184. X   cmdmacs   = NIL(char);
  185. X   targets   = NIL(char);
  186. X
  187. X   Transitive     = TRUE;
  188. X   Nest_level     = 0;
  189. X   Line_number    = 0;
  190. X
  191. X   while( --argc > 0 ) {
  192. X      register char *p;
  193. X      char *q;
  194. X
  195. X      if( *(p = *++argv) == '-' ) {
  196. X         if( p[1] == '\0' ) Fatal("Missing option letter");
  197. X
  198. X         /* copy options to Buffer for $(MFLAGS), strip 'f' */
  199. X         q = strchr(Buffer, 0);
  200. X         while (*p != 0)
  201. X            if( (*q++ = *p++) == 'f' ) q--;
  202. X
  203. X     if( *(q-1) == '-' )
  204. X        q--;
  205. X     else
  206. X            *q++ = ' ';
  207. X
  208. X     *q = 0;
  209. X
  210. X         for( p = *argv+1; *p; p++) switch (*p) {
  211. X        case 'f':
  212. X           if( fil_name == NIL(char) ) {
  213. X          if( *++argv != NIL(char) ) {
  214. X             fil_name = *argv;
  215. X             argc--;
  216. X          } else
  217. X             Fatal("No file name for -f");
  218. X           } else
  219. X          Fatal("Only one `-f file' allowed");
  220. X           break;
  221. X
  222. X        case 'k': Continue   = TRUE;  break;
  223. X        case 'p': Listing    = TRUE;  break;
  224. X        case 'r': Rules      = FALSE; break;
  225. X        case 'n': Trace      = TRUE;  break;
  226. X        case 't': Touch      = TRUE;  break;
  227. X        case 'q': Check      = TRUE;  break;
  228. X        case 'u': Force      = TRUE;  break;
  229. X        case 'v': Verbose    = TRUE;  break;
  230. X        case 'x': m_export   = TRUE;  break;
  231. X        case 'T': Transitive = FALSE; break;
  232. X        case 'e': Get_env    = 'e';   break;
  233. X        case 'E': Get_env    = 'E';   break;
  234. X
  235. X        case 'V': Version();  Quit(NIL(CELL));  break;
  236. X        case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
  237. X        case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
  238. X        case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
  239. X        case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
  240. X
  241. X        case 'P':
  242. X           if( p[1] ) {
  243. X          Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
  244. X          p += strlen(p)-1;
  245. X           }
  246. X           else
  247. X          Fatal( "Missing number for -P flag" );
  248. X           break;
  249. X
  250. X#ifdef HELP
  251. X        case 'h': Usage();  Quit(NIL(CELL));  break;
  252. X#endif
  253. X#ifdef DBUG
  254. X        case '#':
  255. X           DB_PUSH(p+1);
  256. X           p += strlen(p)-1;
  257. X           break;
  258. X#endif
  259. X
  260. X        default:
  261. X           fprintf(stderr, USAGE, Pname);
  262. X           Quit(NIL(CELL));
  263. X           break;
  264. X     }
  265. X      }
  266. X      else if( (q = strchr(p, '=')) != NIL(char) ) {
  267. X     cmdmacs = _stradd( cmdmacs, _strdup(p), TRUE );
  268. X     Parse_macro( p, (strchr(p,'+')==NIL(char))?M_PRECIOUS:M_DEFAULT );
  269. X      }
  270. X      else {
  271. X     register CELLPTR cp;
  272. X     targets = _stradd( targets, _strdup(p), TRUE );
  273. X     Add_fringe(cp = Def_cell(p, NIL(CELL)));
  274. X     cp->ce_flag |= F_TARGET;
  275. X     Target = TRUE;
  276. X      }
  277. X   }
  278. X
  279. X   Def_macro( "MAKEMACROS",  cmdmacs, M_PRECIOUS|M_NOEXPORT );
  280. X   Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
  281. X   if( cmdmacs != NIL(char) ) FREE(cmdmacs);
  282. X   if( targets != NIL(char) ) FREE(targets);
  283. X
  284. X   Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
  285. X   Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
  286. X
  287. X   if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
  288. X
  289. X   _warn  = FALSE;      /* disable warnings for builtin rules */
  290. X   ex_val = Target;     /* make sure we don't mark any        */
  291. X   Target = TRUE;       /* of the default rules as            */
  292. X   Make_rules();        /* potential targets                  */
  293. X   _warn = TRUE;
  294. X
  295. X   if( Rules ) {
  296. X      /* order of precedence is:
  297. X       *
  298. X       *   MAKESTARTUP  from command line (precious is marked)
  299. X       *   MAKESTARTUP  from environment
  300. X       *   MAKESTARTUP  from builtin rules (not precious)
  301. X       */
  302. X      char *fname;
  303. X
  304. X      if( ((hp = GET_MACRO("MAKESTARTUP")) != NIL(HASH)) &&
  305. X      (hp->ht_flag & M_PRECIOUS) &&
  306. X      (mkfil=Openfile(fname=hp->ht_value, FALSE)) != NIL(FILE) ||
  307. X      (mkfil=Openfile(fname=Read_env_string("MAKESTARTUP"), FALSE)) != NIL(FILE) ||
  308. X      hp != NIL(HASH) &&
  309. X      (mkfil=Openfile(fname=hp->ht_value, FALSE)) != NIL(FILE) )
  310. X      {
  311. X         Parse(mkfil);
  312. X         mkfil = NIL(FILE);
  313. X      }
  314. X      else
  315. X         Fatal( "configuration file `%s' not found", fname );
  316. X   }
  317. X
  318. X   Target = ex_val;
  319. X
  320. X   if( Get_env == 'e' ) _do_ReadEnvironment();
  321. X
  322. X   if( fil_name != NIL(char) )
  323. X      mkfil = Openfile( fil_name, TRUE );
  324. X   else {
  325. X      /* Search .MAKEFILES dependent list looking for a makefile.
  326. X       */
  327. X      register CELLPTR cp;
  328. X      register LINKPTR lp;
  329. X
  330. X      cp = Def_cell( ".MAKEFILES", NIL(CELL) );
  331. X
  332. X      if( (lp = cp->CE_PRQ) != NIL(LINK) ) {
  333. X         int s_n, s_t, s_q;
  334. X
  335. X         s_n = Trace;
  336. X         s_t = Touch;
  337. X         s_q = Check;
  338. X
  339. X         Trace = Touch = Check = FALSE;
  340. X         Makemkf = Wait_for_completion = TRUE;
  341. X         mkfil = NIL(FILE);
  342. X
  343. X         for(;  lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
  344. X            mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE );
  345. X
  346. X            if( mkfil == NIL(FILE) &&
  347. X        Make(lp->cl_prq, lp->cl_prq->CE_HOW, NIL(CELL)) != -1 )
  348. X               mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE );
  349. X         }
  350. X
  351. X         Trace = s_n;
  352. X         Touch = s_t;
  353. X         Check = s_q;
  354. X         Makemkf = Wait_for_completion = FALSE;
  355. X      }
  356. X   }
  357. X
  358. X   if( mkfil != NIL(FILE) ) {
  359. X      char *f = Filename();
  360. X      char *p;
  361. X
  362. X      if( strcmp(f, "stdin") == 0 ) f = "-";
  363. X      p = _stradd( "-f", f, FALSE );
  364. X      Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT );
  365. X      Parse( mkfil );
  366. X   }
  367. X   else if( !Rules )
  368. X      Fatal( "No `makefile' present" );
  369. X
  370. X   if( Nest_level     ) Fatal( "Missing .END for .IF" );
  371. X   if( Get_env == 'E' ) _do_ReadEnvironment();
  372. X
  373. X   _do_VPATH();                  /* kludge it up with .SOURCE    */
  374. X
  375. X   if( Listing ) Dump();        /* print out the structures     */
  376. X   if( Trace ) Glob_attr &= ~A_SILENT;    /* make sure we see the trace   */
  377. X
  378. X   if( !Target )
  379. X      Fatal( "No target" );
  380. X   else {
  381. X      Check_circle( Fringe_hd );
  382. X      Check_circle_dfa();
  383. X   }
  384. X
  385. X   TALLOC( Start_dir.ce_name, 1, HASH );
  386. X   Start_dir.CE_NAME = ".SETDIR";
  387. X   Push_dir( &Start_dir, Glob_attr & A_IGNORE );
  388. X
  389. X   if( m_export ) {
  390. X      int i;
  391. X
  392. X      for( i=0; i<HASH_TABLE_SIZE; ++i ) {
  393. X         char *tmpstr = hp->ht_value;
  394. X
  395. X         if( tmpstr == NIL(char) ) tmpstr = "";
  396. X         if( !(hp->ht_flag & M_NOEXPORT) &&
  397. X         Write_env_string(hp->ht_name, tmpstr) != 0 )
  398. X            Warning( "Could not export %s", hp->ht_name );
  399. X      }
  400. X   }
  401. X   if( Buffer != NIL(char) ) FREE( Buffer );
  402. X   if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
  403. X   if( Glob_attr & A_SEQ ) Def_macro( "MAXPROCESS", "1", M_EXPANDED|M_FORCE );
  404. X
  405. X   ex_val = Make_targets();
  406. X
  407. X   Pop_dir( (Glob_attr & A_IGNORE) != 0 );
  408. X   Clear_signals();
  409. X   Epilog(ex_val);      /* Does not return -- EVER */
  410. X}
  411. X
  412. X
  413. Xstatic void
  414. X_do_ReadEnvironment()
  415. X{
  416. X   t_attr saveattr = Glob_attr;
  417. X
  418. X   Glob_attr |= A_SILENT;
  419. X   ReadEnvironment();
  420. X   Glob_attr = saveattr;
  421. X}
  422. X
  423. X
  424. Xstatic void
  425. X_do_VPATH()
  426. X{
  427. X   HASHPTR hp;
  428. X   char    *_rl[2];
  429. X   extern char **Rule_tab;
  430. X
  431. X   hp = GET_MACRO("VPATH");
  432. X   if( hp == NIL(HASH) ) return;
  433. X
  434. X   _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
  435. X   _rl[1] = NIL(char);
  436. X
  437. X   Rule_tab = _rl;
  438. X   Parse( NIL(FILE) );
  439. X}
  440. X
  441. X
  442. X/*  The file table and pointer to the next FREE slot for use by both
  443. X    Openfile and Closefile.  Each open stacks the new file onto the open
  444. X    file stack, and a corresponding close will close the passed file, and
  445. X    return the next file on the stack.  The maximum number of nested
  446. X    include files is limited by the value of MAX_INC_DEPTH */
  447. X
  448. Xstatic struct {
  449. X   FILE         *file;      /* file pointer                 */
  450. X   char         *name;      /* name of file                 */
  451. X   int          numb;       /* line number                  */
  452. X} ftab[ MAX_INC_DEPTH ];
  453. X
  454. Xstatic int next_file_slot = 0;
  455. X
  456. X/* Set the proper macro value to reflect the depth of the .INCLUDE directives.
  457. X */
  458. Xstatic void
  459. X_set_inc_depth()
  460. X{
  461. X   char buf[10];
  462. X   sprintf( buf, "%d", next_file_slot-1 );
  463. X   Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
  464. X}
  465. X
  466. X
  467. XFILE *
  468. XOpenfile(name, err)/*
  469. X=====================
  470. X   This routine opens a file for input.
  471. X   If the file name is `-' then it returns standard input.
  472. X   The file is pushed onto the open file stack.  */
  473. Xchar *name;
  474. Xint  err;
  475. X{
  476. X   FILE *fil;
  477. X
  478. X   DB_ENTER("Openfile");
  479. X
  480. X   if( name == NIL(char) || !*name )
  481. X      if( !err )
  482. X         DB_RETURN(NIL(FILE));
  483. X      else
  484. X         Fatal( "Openfile:  NIL filename" );
  485. X   
  486. X   if( next_file_slot == MAX_INC_DEPTH )
  487. X      Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
  488. X
  489. X   DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
  490. X
  491. X   if( strcmp("-", name) == 0 ) {
  492. X      name = "stdin";
  493. X      fil = stdin;
  494. X   }
  495. X   else
  496. X      fil = fopen( name, "r" );
  497. X
  498. X   if( fil == NIL(FILE) ) {
  499. X      if( err )
  500. X         Fatal( "File %s not found", name );
  501. X   }
  502. X   else {
  503. X      ftab[next_file_slot].file   = fil;
  504. X      ftab[next_file_slot].numb   = Line_number;
  505. X      ftab[next_file_slot++].name = _strdup(name);
  506. X      Line_number = 0;
  507. X      _set_inc_depth();
  508. X   }
  509. X
  510. X   DB_RETURN(fil);
  511. X}
  512. X
  513. XFILE *
  514. XClosefile()/*
  515. X=============
  516. X   This routine is used to close the last file opened.  This forces make
  517. X   to open files in a last open first close fashion.  It returns the
  518. X   file pointer to the next file on the stack, and NULL if the stack is empty.*/
  519. X{
  520. X   DB_ENTER("Closefile");
  521. X
  522. X   if( !next_file_slot )
  523. X      DB_RETURN( NIL(FILE) );
  524. X
  525. X   if( ftab[--next_file_slot].file != stdin ) {
  526. X      DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
  527. X      fclose( ftab[next_file_slot].file );
  528. X      FREE( ftab[next_file_slot].name );
  529. X      _set_inc_depth();
  530. X   }
  531. X
  532. X   if( next_file_slot > 0 ) {
  533. X      Line_number = ftab[next_file_slot].numb;
  534. X      DB_RETURN( ftab[next_file_slot-1].file );
  535. X   }
  536. X   else
  537. X      Line_number = 0;
  538. X
  539. X   DB_RETURN( NIL(FILE) );
  540. X}
  541. X
  542. X
  543. Xchar *
  544. XFilename()/*
  545. X============
  546. X   Return name of file on top of stack */
  547. X{
  548. X   return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
  549. X}
  550. X
  551. X/*
  552. X** print error message from variable arg list
  553. X*/
  554. X
  555. Xstatic int errflg = TRUE;
  556. Xstatic int warnflg = FALSE;
  557. X
  558. Xstatic void
  559. Xerrargs(fmt, args)
  560. Xchar    *fmt;
  561. Xva_list  args;
  562. X{
  563. X   int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
  564. X
  565. X   if( errflg || warn ) {
  566. X      char *f = Filename();
  567. X
  568. X      fprintf( stderr, "%s:  ", Pname );
  569. X      if( f != NIL(char) ) fprintf(stderr, "%s:  line %d:  ", f, Line_number);
  570. X
  571. X      if( errflg )
  572. X         fprintf(stderr, "Error -- ");
  573. X      else if( warn )
  574. X         fprintf(stderr, "Warning -- ");
  575. X
  576. X      vfprintf( stderr, fmt, args );
  577. X      putc( '\n', stderr );
  578. X      if( errflg && !Continue ) Quit( NIL(CELL) );
  579. X   }
  580. X}
  581. X
  582. X/*
  583. X** Print error message and abort
  584. X*/
  585. Xint
  586. XFatal(fmt, va_alist)
  587. Xchar *fmt;
  588. Xva_dcl;
  589. X{
  590. X   va_list args;
  591. X
  592. X   va_start(args, fmt);
  593. X   Continue = FALSE;
  594. X   errargs(fmt, args);
  595. X   va_end(args);
  596. X}
  597. X
  598. X/*
  599. X** error message and exit (unless -k)
  600. X*/
  601. Xint
  602. XError(fmt, va_alist)
  603. Xchar*   fmt;
  604. Xva_dcl;
  605. X{
  606. X   va_list args;
  607. X
  608. X   va_start(args, fmt);
  609. X   errargs(fmt, args);
  610. X   va_end(args);
  611. X}
  612. X
  613. X
  614. X/*
  615. X** non-fatal message
  616. X*/
  617. Xint
  618. XWarning(fmt, va_alist)
  619. Xchar *fmt;
  620. Xva_dcl;
  621. X{
  622. X   va_list args;
  623. X
  624. X   va_start(args, fmt);
  625. X   warnflg = TRUE;
  626. X   errflg = FALSE;
  627. X   errargs(fmt, args);
  628. X   errflg = TRUE;
  629. X   warnflg = FALSE;
  630. X   va_end(args);
  631. X}
  632. X
  633. X
  634. Xvoid
  635. XNo_ram()
  636. X{
  637. X   Fatal( "No more memory" );
  638. X}
  639. X
  640. X
  641. X#ifdef HELP
  642. XUsage()
  643. X{
  644. X   printf(USAGE, Pname);
  645. X   puts("    -P#       - set max number of child processes for parallel make");
  646. X   puts("    -f file   - use file as the makefile\n");
  647. X
  648. X   puts("Options: (can be catenated, ie -irn == -i -r -n)");
  649. X   puts("    -A   - enable AUGMAKE special target mapping");
  650. X   puts("    -e   - define environment strings as macros");
  651. X   puts("    -E   - same as -e but done after parsing makefile");
  652. X   puts("    -h   - print out usage info");
  653. X   puts("    -i   - ignore errors");
  654. X   puts("    -k   - make independent targets, even if errors");
  655. X   puts("    -n   - trace and print, do not execute commands");
  656. X   puts("    -p   - print out a version of the makefile");
  657. X   puts("    -q   - check if target is up to date.  Does not do");
  658. X   puts("           anything.  Returns 0 if up to date, 1 otherwise");
  659. X   puts("    -r   - don't use internal rules");
  660. X   puts("    -s   - do your work silently");
  661. X   puts("    -S   - disable parallel (force sequential) make, overrides -P");
  662. X   puts("    -t   - touch, update time stamps without executing commands");
  663. X   puts("    -T   - do not apply transitive closure");
  664. X   puts("    -u   - force unconditional update of target");
  665. X   puts("    -v   - verbose, print out what we are doing");
  666. X   puts("    -V   - print out version number");
  667. X   puts("    -x   - export macro values to environment");
  668. X}
  669. X#endif
  670. X
  671. X
  672. XVersion()
  673. X{
  674. X   extern char **Rule_tab;
  675. X   char **p;
  676. X   
  677. X   printf("%s - %s, ", Pname, COPYRIGHT);
  678. X   printf("Version %s, Patch Level %d\n\n", VERSION, PATCHLEVEL);
  679. X
  680. X   puts("Default Configuration:");
  681. X   for (p=Rule_tab;  *p != NIL(char);  p++)
  682. X      printf("\t%s\n", *p);
  683. X}
  684. SHAR_EOF
  685. chmod 0440 dmake.c || echo "restore of dmake.c fails"
  686. echo "x - extracting dag.c (Text)"
  687. sed 's/^X//' << 'SHAR_EOF' > dag.c &&
  688. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dag.c,v 1.1 90/10/06 12:03:33 dvadura Exp $
  689. X-- SYNOPSIS -- Routines to construct the internal dag.
  690. X-- 
  691. X-- DESCRIPTION
  692. X--    This file contains all the routines that are responsible for
  693. X--    defining and manipulating all objects used by the make facility.
  694. X-- 
  695. X-- AUTHOR
  696. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  697. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  698. X--
  699. X-- COPYRIGHT
  700. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  701. X-- 
  702. X--      This program is free software; you can redistribute it and/or
  703. X--      modify it under the terms of the GNU General Public License
  704. X--      (version 1), as published by the Free Software Foundation, and
  705. X--      found in the file 'LICENSE' included with this distribution.
  706. X-- 
  707. X--      This program is distributed in the hope that it will be useful,
  708. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  709. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  710. X--      GNU General Public License for more details.
  711. X-- 
  712. X--      You should have received a copy of the GNU General Public License
  713. X--      along with this program;  if not, write to the Free Software
  714. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  715. X--
  716. X-- LOG
  717. X--     $Log:    dag.c,v $
  718. X * Revision 1.1  90/10/06  12:03:33  dvadura
  719. X * dmake Release, Version 3.6
  720. X * 
  721. X*/
  722. X
  723. X#include <ctype.h>
  724. X#include "extern.h"
  725. X#include "alloc.h"
  726. X#include "db.h"
  727. X
  728. X
  729. XHASHPTR
  730. XGet_name( name, tab, define, dir )/*
  731. X====================================
  732. X    Look to see if the name is defined, if it is then return
  733. X    a pointer to its node, if not return NIL(HASH).
  734. X    If define is TRUE and the name is not found it will be added. */
  735. X
  736. Xchar    *name;            /* name we are looking for   */
  737. XHASHPTR *tab;            /* the hash table to look in */
  738. Xint    define;            /* TRUE => add to table      */
  739. XCELLPTR dir;
  740. X{
  741. X   register HASHPTR hp;
  742. X   register char    *p;
  743. X   uint16           hv;
  744. X   uint32           hash_key;
  745. X
  746. X   DB_ENTER( "Get_name" );
  747. X   DB_PRINT( "name", ("Looking for %s", name) );
  748. X
  749. X   hv = Hash( name, &hash_key );
  750. X
  751. X   for( hp = tab[ hv ]; hp != NIL(HASH); hp = hp->ht_next )
  752. X      if( hp->ht_hash == hash_key &&
  753. X      (tab != Defs || ((tab == Defs) && (hp->CP_ROOT == dir))) &&
  754. X      !strcmp(hp->ht_name, name) )
  755. X         break;
  756. X
  757. X   if( hp == NIL(HASH) && define ) {
  758. X      /* Check to make sure that CELL name contains only printable chars */
  759. X      for( p=name; *p; p++ )
  760. X     if( !isprint(*p) )
  761. X        Fatal( "Name contains non-printable character [0x%02x]", *p );
  762. X
  763. X      TALLOC( hp, 1, HASH );        /* allocate a cell and add it in */
  764. X
  765. X      if( tab == Defs ) hp->CP_ROOT = dir;
  766. X      hp->ht_name  = _strdup( name );
  767. X      hp->ht_hash  = hash_key;
  768. X      hp->ht_next  = tab[ hv ];
  769. X      tab[ hv ]    = hp;
  770. X
  771. X      DB_PRINT( "name", ("Adding %s", name) );
  772. X   }
  773. X
  774. X   DB_PRINT( "name",("Returning: [%s,%lu]",
  775. X         (hp == NIL(HASH)) ? "":hp->ht_name, hv) );
  776. X   DB_RETURN( hp );
  777. X}
  778. X
  779. X
  780. X
  781. XHASHPTR
  782. XDef_macro( name, value, flags )/*
  783. X=================================
  784. X   This routine is used to define a macro, and it's value.
  785. X   The flags indicates if it is a permanent macro or if it's value
  786. X   can be redefined.  A flags of M_PRECIOUS means it is a precious
  787. X   macro and cannot be further redefined.  If the flags flag also
  788. X   contains the M_MULTI bit it means that the macro can be redefined
  789. X   multiple times and no warning of the redefinitions should be issued.
  790. X   Once a macro's VAR flags are set they are preserved through all future
  791. X   macro definitions.
  792. X   
  793. X   Macro definitions that have one of the variable bits set are treated
  794. X   specially.  In each case the hash table entry var field points at the
  795. X   global variable that can be set by assigning to the macro.
  796. X   
  797. X   bit valued global vars must be computed when the macro value is changed.
  798. X   char valued global vars must have the first char of ht_value copied to
  799. X   them.  string valued global vars have the same value as ht_value and should
  800. X   just have the new value of ht_value copied to them.  */
  801. X
  802. Xchar    *name;            /* macro name to define    */
  803. Xchar    *value;            /* macro value to set    */
  804. Xint     flags;            /* initial ht_flags    */
  805. X{
  806. X   register HASHPTR   hp;
  807. X   register char      *p, *q;
  808. X
  809. X   DB_ENTER( "Def_macro" );
  810. X   DB_PRINT( "mac", ("Defining macro %s = %s, %x", name, value, flags) );
  811. X
  812. X   /* check to see if name is in the table, if so then just overwrite
  813. X      the previous definition.  Otherwise allocate a new node, and
  814. X      stuff it in the hash table, at the front of any linked list */
  815. X
  816. X   if( Readenv ) flags |= M_LITERAL;
  817. X
  818. X   hp = Get_name( name, Macs, TRUE, NIL(CELL) );
  819. X
  820. X   if( (hp->ht_flag & M_PRECIOUS) && !(flags & M_FORCE) ) {
  821. X      Warning( "Macro `%s' cannot be redefined", name );
  822. X      DB_RETURN( hp );
  823. X   }
  824. X
  825. X   if( hp->ht_value != NIL(char) ) FREE( hp->ht_value );
  826. X
  827. X   if( (hp->ht_flag & M_USED) && !((flags | hp->ht_flag) & M_MULTI) )
  828. X      Warning( "Macro `%s' redefined after use", name );
  829. X
  830. X   if( (value != NIL(char)) && (*value) ) {
  831. X      /* strip out any \<nl> combinations where \ is the current CONTINUATION
  832. X       * char */
  833. X
  834. X      for( p = value; (p = strchr(p, CONTINUATION_CHAR)) != NIL(char); )
  835. X         if( p[1] == '\n' )
  836. X        strcpy( p, p+2 );
  837. X     else
  838. X        p++;
  839. X
  840. X      if( !(flags & M_LITERAL) ) {
  841. X     p = _strdup( _strspn( value, " \t" ) ); /* strip white space before */
  842. X                         /* ... and after value         */
  843. X     if( *p ) {
  844. X        for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--);
  845. X        *++q = '\0';
  846. X     }
  847. X     flags &= ~M_LITERAL;
  848. X      }
  849. X      else
  850. X     p = _strdup( value );               /* take string literally   */
  851. X      
  852. X      if( !*p )    {                /* check if result is ""   */
  853. X         FREE( p );
  854. X         p = NIL(char);
  855. X     flags |= M_EXPANDED;
  856. X      }
  857. X      else if( *_strpbrk( p, "${}" ) == '\0' )
  858. X     flags |= M_EXPANDED;
  859. X
  860. X      hp->ht_value = p;
  861. X   }
  862. X   else
  863. X      hp->ht_value = NIL(char);
  864. X
  865. X   /* Assign the hash table flag less the M_MULTI flag, it is used only
  866. X    * to silence the warning.  But carry it over if it was previously
  867. X    * defined in ht_flag, as this is a permanent M_MULTI variable. */
  868. X
  869. X   hp->ht_flag = (flags & ~(M_MULTI|M_FORCE)) |
  870. X         (hp->ht_flag & (M_VAR_MASK | M_MULTI));
  871. X   
  872. X   /* Check for macro variables and make the necessary adjustment in the
  873. X    * corresponding global variables */
  874. X    
  875. X   if( hp->ht_flag & M_VAR_MASK )
  876. X      if( !(flags & M_EXPANDED) )
  877. X     Error( "Macro variables must be assigned with :=" );
  878. X      else switch( hp->ht_flag & M_VAR_MASK )    /* only one var type per var */
  879. X      {
  880. X     case M_VAR_STRING:
  881. X        *hp->MV_SVAR = hp->ht_value;
  882. X        break;
  883. X
  884. X     case M_VAR_CHAR:
  885. X        *hp->MV_CVAR = (hp->ht_value == NIL(char)) ? '\0':*hp->ht_value;
  886. X        break;
  887. X  
  888. X     case M_VAR_INT: {
  889. X        int tvalue;
  890. X        if( hp->MV_IVAR == NIL(int) ) break;    /* first time */
  891. X
  892. X        tvalue = atoi(hp->ht_value);
  893. X        if( hp->MV_IVAR == &Buffer_size ) {
  894. X           /* If Buffer_size is modified then make sure you change the
  895. X            * size of the real buffer as well. */
  896. X           tvalue = (tvalue < (BUFSIZ-2)) ? BUFSIZ : tvalue+2;
  897. X           if( Buffer_size == tvalue ) break;
  898. X           if( Buffer ) FREE(Buffer);
  899. X           if((Buffer=MALLOC(tvalue, char)) == NIL(char)) No_ram();
  900. X           *Buffer = '\0';
  901. X        }
  902. X        *hp->MV_IVAR = tvalue;
  903. X
  904. X        if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
  905. X           if( tvalue < 1 )
  906. X          Fatal( "Process limit value must be > 1" );
  907. X
  908. X           if( Max_proc > Max_proclmt )
  909. X          Fatal( "Specified # of processes exceeds limit of [%d]",
  910. X             Max_proclmt );
  911. X        }
  912. X     } break;
  913. X     case M_VAR_BIT:
  914. X        /* Bit variables are set to 1 if ht_value is not NULL and 0
  915. X         * otherwise */
  916. X         
  917. X        if( hp->ht_value == NIL(char) )
  918. X           *hp->MV_BVAR &= ~hp->MV_MASK;
  919. X        else
  920. X           *hp->MV_BVAR |= hp->MV_MASK;
  921. X        break;
  922. X      }
  923. X   
  924. X   DB_RETURN( hp );
  925. X}
  926. X
  927. X
  928. X
  929. XCELLPTR
  930. XDef_cell( name, dir )/*
  931. X=======================
  932. X   Take a string passed in and define it as a cell
  933. X   If the cell exists then return a pointer to it. */
  934. Xchar    *name;
  935. XCELLPTR dir;
  936. X{
  937. X   register HASHPTR  hp;
  938. X   register CELLPTR  cp;
  939. X   register CELLPTR  lib;
  940. X   char             *member;
  941. X   char             *end;
  942. X
  943. X   DB_ENTER( "Def_cell" );
  944. X
  945. X   /* Check to see if the cell is a member of the form lib(member) or
  946. X    * lib((symbol)) and handle the cases appropriately.
  947. X    * What we do is we look at the target, if it is of the above two
  948. X    * forms we get the lib, and add the member/symbol to the list of
  949. X    * prerequisites for the library.  If this is a symbol name def'n
  950. X    * we additionally add the attribute A_SYMBOL, so that stat can
  951. X    * try to do the right thing.  */
  952. X
  953. X   if( ((member = strchr(name, '('))     != NIL(char)) &&
  954. X       ((end    = strrchr(member,  ')')) != NIL(char)) &&
  955. X       (member > name) && (member[-1] != '$') &&
  956. X       (end > member+1)  && (end[1] == '\0') )
  957. X   {
  958. X      *member++ = *end = '\0';
  959. X
  960. X      if( (*member == '(') && (member[strlen(member)-1] == ')') ) {
  961. X     member[ strlen(member)-1 ] = '\0';
  962. X     cp = Def_cell( member+1, dir );
  963. X     cp->ce_attr |= A_SYMBOL;
  964. X      }
  965. X      else
  966. X     cp = Def_cell( member, dir );
  967. X
  968. X      lib  = Def_cell( name, dir );
  969. X
  970. X      if( lib->CE_HOW == NIL(HOW) ) TALLOC( lib->CE_HOW, 1, HOW );
  971. X
  972. X      Add_prerequisite( lib->CE_HOW, cp, FALSE );
  973. X      lib->ce_attr |= A_LIBRARY | A_COMPOSITE;
  974. X
  975. X      if( !Def_targets ) cp = lib;
  976. X   }
  977. X   else {
  978. X      hp = Get_name( name, Defs, TRUE, dir );/* get the name from hash table */
  979. X
  980. X      if( hp->CP_OWNR == NIL(CELL) )    /* was it previously defined    */
  981. X      {                    /* NO, so define a new cell    */
  982. X     DB_PRINT( "cell", ("Defining cell [%s]", name) );
  983. X
  984. X     TALLOC( cp, 1, CELL );
  985. X     hp->CP_OWNR = cp;
  986. X     cp->ce_name = hp;
  987. X      }
  988. X      else                 /* YES, so return the old cell    */
  989. X      {
  990. X     DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) );
  991. X     cp = hp->CP_OWNR;
  992. X      }
  993. X   }
  994. X
  995. X   DB_RETURN( cp );
  996. X}
  997. X
  998. X
  999. X
  1000. X
  1001. XLINKPTR
  1002. XAdd_prerequisite( how, cell, head )/*
  1003. X=====================================
  1004. X    Add a dependency node to the dag.  It adds it to the prerequisites,
  1005. X    if any, of the cell and makes certain they are in linear order.
  1006. X    If head == 1, then add to head of the prerequisite list, else
  1007. X    add to tail. */
  1008. X
  1009. XHOWPTR  how;
  1010. XCELLPTR cell;
  1011. Xint     head;
  1012. X{
  1013. X   register LINKPTR lp, tlp;
  1014. X
  1015. X   DB_ENTER( "Add_prerequisite" );
  1016. X   DB_PRINT( "cell", ("Defining prerequisite %s", cell->CE_NAME) );
  1017. X
  1018. X   if( (cell->ce_flag & (F_MAGIC | F_PERCENT)) )
  1019. X      Fatal( "Special target [%s] cannot be a prerequisite",
  1020. X             cell->CE_NAME );
  1021. X
  1022. X   if( how->hw_prq == NIL(LINK) ) {    /* it's the first one    */
  1023. X      TALLOC( lp, 1, LINK );
  1024. X      lp->cl_prq    = cell;
  1025. X      how->hw_prq   = lp;
  1026. X   }
  1027. X   else    {    /* search the list, checking for duplicates    */
  1028. X      for( lp = how->hw_prq;
  1029. X       (lp->cl_next != NIL(LINK)) && (lp->cl_prq != cell);
  1030. X       lp = lp->cl_next );
  1031. X
  1032. X      /* If the cell is not found and we are at the last cell in the list,
  1033. X       * allocate a new cell and place it into the list, insert it at the
  1034. X       * head if head == 1, else we add it to the end. */
  1035. X
  1036. X      if( (lp->cl_prq != cell) ) {
  1037. X     TALLOC( tlp, 1, LINK );
  1038. X     tlp->cl_prq = cell;
  1039. X
  1040. X     if( head ) {
  1041. X        tlp->cl_next = how->hw_prq;
  1042. X        how->hw_prq  = tlp;
  1043. X     }
  1044. X     else
  1045. X        lp->cl_next  = tlp;
  1046. X
  1047. X     lp = tlp;
  1048. X      }
  1049. X   }
  1050. X
  1051. X   DB_RETURN( lp );
  1052. X}
  1053. X
  1054. X
  1055. X
  1056. Xvoid
  1057. XClear_prerequisites( how )/*
  1058. X============================
  1059. X    Clear out the list of prerequisites, freeing all of the LINK nodes,
  1060. X    and setting the list to NULL */
  1061. XHOWPTR how;
  1062. X{
  1063. X   LINKPTR lp, tlp;
  1064. X
  1065. X   DB_ENTER( "Clear_prerequisites" );
  1066. X   DB_PRINT( "cell", ("Nuking prerequisites") );
  1067. X
  1068. X   if( how == NIL(HOW) ) { DB_VOID_RETURN; }
  1069. X
  1070. X   for( lp=how->hw_prq; lp != NIL(LINK); lp=tlp ) {
  1071. X      tlp=lp->cl_next;
  1072. X      FREE( lp );
  1073. X   }
  1074. X
  1075. X   how->hw_prq = NIL(LINK);
  1076. X
  1077. X   DB_VOID_RETURN;
  1078. X}
  1079. X
  1080. X
  1081. X
  1082. Xvoid
  1083. XAdd_fringe( cp )/*
  1084. X================== Take the cell pointed to by cp and put it at the end
  1085. X           of the fringe of targets */
  1086. XCELLPTR cp;
  1087. X{
  1088. X   DB_ENTER( "Add_fringe" );
  1089. X
  1090. X   if( !(cp->ce_attr & A_FRINGE) ) {
  1091. X      DB_PRINT( "cell", ("Adding to fringe %s", cp->ce_name->ht_name) );
  1092. X
  1093. X      if( Fringe_hd == NIL(LINK) ) {
  1094. X     TALLOC( Fringe_hd, 1, LINK );
  1095. X     Fringe_tl = Fringe_hd;
  1096. X      }
  1097. X      else if( Fringe_tl != NIL(LINK) ) {
  1098. X     TALLOC( Fringe_tl->cl_next, 1, LINK );
  1099. X     Fringe_tl = Fringe_tl->cl_next;
  1100. X      }
  1101. X
  1102. X      Fringe_tl->cl_prq = cp;
  1103. X      cp->ce_attr |= A_FRINGE;
  1104. X   }
  1105. X
  1106. X   DB_VOID_RETURN;
  1107. X}
  1108. X
  1109. X
  1110. X
  1111. X
  1112. Xvoid
  1113. XCheck_circle( lp )/*
  1114. X====================
  1115. X    Check for circular definitions in the make graph */
  1116. XLINKPTR lp;
  1117. X{
  1118. X   for( ; lp != NIL(LINK); lp = lp->cl_next )
  1119. X      if( Test_circle( lp->cl_prq, FALSE ) )
  1120. X     Fatal( "Detected circular dependency in graph at [%s]",
  1121. X        lp->cl_prq->CE_NAME );
  1122. X}
  1123. X
  1124. X
  1125. X
  1126. X
  1127. Xint
  1128. XTest_circle( cp, meta )/*
  1129. X=========================
  1130. X    Actually run through the graph */
  1131. XCELLPTR cp;
  1132. Xint     meta;
  1133. X{
  1134. X   int res = 0;
  1135. X   DB_ENTER( "Test_circle" );
  1136. X   DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) );
  1137. X
  1138. X   if( cp->ce_flag & F_MARK )
  1139. X      DB_RETURN( (cp->ce_attr & A_LIBRARY) ? 0 : 1 );
  1140. X
  1141. X   cp->ce_flag |= F_MARK;
  1142. X
  1143. X   if( meta ) {
  1144. X      register EDGEPTR ep;
  1145. X
  1146. X      if( cp->CE_EDGES != NIL(EDGE) ) {
  1147. X     EDGEPTR es;
  1148. X
  1149. X     ep = es = cp->CE_EDGES;
  1150. X     do {
  1151. X        if( ep->ed_prq != NIL(CELL) && ep->ed_prq->ce_flag & F_DFA )
  1152. X           res = Test_circle( ep->ed_prq, TRUE );
  1153. X        ep = ep->ed_next;
  1154. X     }
  1155. X     while( ep != es && !res );
  1156. X      }
  1157. X   }
  1158. X   else {
  1159. X      register LINKPTR tcp;
  1160. X
  1161. X      if( cp->CE_HOW != NIL(HOW) )
  1162. X     for( tcp = cp->CE_HOW->hw_prq; !res && tcp != NIL(LINK);
  1163. X          tcp = tcp->cl_next )
  1164. X        if( tcp->cl_prq != cp ) res = Test_circle( tcp->cl_prq, FALSE );
  1165. X   }
  1166. X
  1167. X   cp->ce_flag ^= F_MARK;
  1168. X   DB_RETURN( res );
  1169. X}
  1170. X
  1171. X
  1172. X
  1173. X
  1174. XSTRINGPTR
  1175. XDef_recipe( rcp, sp, white_too, no_check )/*
  1176. X=============================================
  1177. X    Take the recipe and add it to the list of recipes
  1178. X    pointed to by sp.  sp points to the last element.
  1179. X    return a pointer to the new recipe.  If white_too == TRUE add the
  1180. X    recipe even if it contains only white space.
  1181. X    If no_check is true then don't look for -@ at the start of the
  1182. X    recipe line. */
  1183. Xchar      *rcp;
  1184. XSTRINGPTR sp;
  1185. Xint       white_too;
  1186. Xint       no_check;
  1187. X{
  1188. X   register STRINGPTR nsp;
  1189. X   register char      *rp;
  1190. X   t_attr             flag;
  1191. X   int                done;
  1192. X
  1193. X   DB_ENTER( "Def_recipe" );
  1194. X   DB_PRINT( "rul", ("Defining recipe %s", rcp) );
  1195. X
  1196. X   if( !white_too ) rcp = _strspn( rcp, " \t" );
  1197. X   if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) )
  1198. X      DB_RETURN( sp );         /* return last recipe when new recipe not added */
  1199. X
  1200. X   rp = no_check ? rcp : _strspn( rcp, " \t@-+%" );
  1201. X
  1202. X   TALLOC( nsp, 1, STRING );
  1203. X   nsp->st_string = _strdup( rp );
  1204. X
  1205. X   if( sp != NIL(STRING) ) sp->st_next = nsp;
  1206. X   nsp->st_next = NIL(STRING);
  1207. X
  1208. X   if( no_check ) DB_RETURN( nsp );
  1209. X
  1210. X   for( flag = A_DEFAULT, rp = rcp, done = FALSE; !done; )
  1211. X      switch( *rp++ )
  1212. X      {
  1213. X     case '@' : flag |= A_SILENT; break;
  1214. X     case '-' : flag |= A_IGNORE; break;
  1215. X     case '+' : flag |= A_SHELL;  break;
  1216. X     case '%' : flag |= A_SWAP;   break;
  1217. X
  1218. X     case ' ' :
  1219. X     case '\t': break;
  1220. X
  1221. X     default: done = TRUE; break;
  1222. X      }
  1223. X
  1224. X   nsp->st_attr |= flag;
  1225. X
  1226. X   DB_RETURN( nsp );
  1227. X}
  1228. SHAR_EOF
  1229. chmod 0440 dag.c || echo "restore of dag.c fails"
  1230. echo mkdir - common
  1231. mkdir common
  1232. echo "x - extracting common/stdmacs.h (Text)"
  1233. sed 's/^X//' << 'SHAR_EOF' > common/stdmacs.h &&
  1234. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/stdmacs.h,v 1.1 90/10/06 12:04:47 dvadura Exp $
  1235. X-- SYNOPSIS -- general use macros.
  1236. X-- 
  1237. X-- DESCRIPTION
  1238. X--     ANSI macro relies on the fact that it can be replaced by (), or by
  1239. X--    its value, where the value is one value due to the preprocessors
  1240. X--    handling of arguments that are surrounded by ()'s as a single
  1241. X--    argument.
  1242. X--
  1243. X-- AUTHOR
  1244. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1245. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1246. X--
  1247. X-- COPYRIGHT
  1248. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1249. X-- 
  1250. X--      This program is free software; you can redistribute it and/or
  1251. X--      modify it under the terms of the GNU General Public License
  1252. X--      (version 1), as published by the Free Software Foundation, and
  1253. X--      found in the file 'LICENSE' included with this distribution.
  1254. X-- 
  1255. X--      This program is distributed in the hope that it will be useful,
  1256. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1257. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1258. X--      GNU General Public License for more details.
  1259. X-- 
  1260. X--      You should have received a copy of the GNU General Public License
  1261. X--      along with this program;  if not, write to the Free Software
  1262. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1263. X--
  1264. X-- LOG
  1265. X--     $Log:    stdmacs.h,v $
  1266. X * Revision 1.1  90/10/06  12:04:47  dvadura
  1267. X * dmake Release, Version 3.6
  1268. X * 
  1269. X*/
  1270. X
  1271. X#ifndef    MACROS_h
  1272. X#define    MACROS_h
  1273. X
  1274. X#if defined(__STDC__) || defined(__TURBOC__)
  1275. X#define    ANSI(x)    x
  1276. X#else
  1277. X#define    ANSI(x)    ()
  1278. X#endif
  1279. X
  1280. X#define    NIL(p)    ((p*)NULL)
  1281. X#define    offsetof(type,id) ((size_t)&((type*)NULL)->id)
  1282. X
  1283. X#define    FALSE    0
  1284. X#define    TRUE    1
  1285. X
  1286. X#endif
  1287. X
  1288. SHAR_EOF
  1289. chmod 0440 common/stdmacs.h || echo "restore of common/stdmacs.h fails"
  1290. echo "x - extracting common/print.mk (Text)"
  1291. sed 's/^X//' << 'SHAR_EOF' > common/print.mk &&
  1292. X# Make a listing of either everything so far, or just the stuff that has
  1293. X# been updated since the last time a printout was made.
  1294. X# The targets are:
  1295. X#    print        - to print only updated files.
  1296. X#    printall    - to print entire tree.
  1297. X#
  1298. X# MACROS are:
  1299. X#    PRINTER        - printer name on which to put output, output
  1300. X#              goes to a file if no printer name is given.
  1301. X#    PRINTFLAGS    - flags to pass to the printer.
  1302. X#    PRINTEXCLUDE    - substrings in file names not to include in output.
  1303. X
  1304. XGROUPFLAGS  :=
  1305. XSEDLIST = _sed_e_flag_'/{ $(PRINTEXCLUDE) }/d'
  1306. XFILIST  = $(TMPDIR)/pr$$$$
  1307. XOFILE   = $(TMPDIR)/pr$$$$.out
  1308. X
  1309. X.IF $(PRINTEXCLUDE)
  1310. X   SEDARGS = $(SEDLIST:s/_sed_e_flag_/-e /)
  1311. X.END
  1312. X
  1313. Xprintall : print_remove_ctl print;
  1314. Xprint_remove_ctl:;@-$(RM) control/print
  1315. X
  1316. Xprint:
  1317. X@[
  1318. X   if [ -f control/print ]; then
  1319. X      find . -type f -newer control/print -print |\
  1320. X      sort -t. +2 +1 -2 |\
  1321. X      sed $(SEDARGS) >$(FILIST);
  1322. X      if [ -s $(FILIST) ]; then
  1323. X     find . -type f -print | sort -t. +2 +1 -2 |\
  1324. X     sed $(SEDARGS) >$(FILIST).full;
  1325. X     cpr -c -T control/title -N -C `cat $(FILIST).full` >$(OFILE);
  1326. X     cpr -c -N `cat $(FILIST)` >> $(OFILE);
  1327. X     $(RM) $(FILIST).full;
  1328. X      else
  1329. X     echo "No modified files since last printing";
  1330. X      fi
  1331. X   else
  1332. X      find . -type f -print | sort -t. +2 +1 -2 |\
  1333. X      sed $(SEDARGS) >$(FILIST);
  1334. X      if [ -s $(FILIST) ]; then
  1335. X     cpr -c -T control/title -N `cat $(FILIST)` >$(OFILE);
  1336. X      fi
  1337. X   fi
  1338. X
  1339. X   if [ -s $(OFILE) ]; then
  1340. X.IF $(PRINTER)
  1341. X      $(PRINT) $(PRINTFLAGS) $(OFILE);
  1342. X      echo "Listing printed on $(PRINTER)";
  1343. X.IF $(PRINTKEEPTMP) == $(NULL)
  1344. X      $(RM) $(OFILE);
  1345. X.END
  1346. X.ELSE
  1347. X      echo "Listing can be temporarily found in $(OFILE)";
  1348. X.END
  1349. X   fi
  1350. X.IF $(PRINTKEEPTMP) == $(NULL)
  1351. X   $(RM) $(FILIST)
  1352. X.END
  1353. X   touch control/print;
  1354. X   exit 0
  1355. X]
  1356. SHAR_EOF
  1357. chmod 0662 common/print.mk || echo "restore of common/print.mk fails"
  1358. echo "x - extracting common/malloc.c (Text)"
  1359. sed 's/^X//' << 'SHAR_EOF' > common/malloc.c &&
  1360. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/malloc.c,v 1.1 90/10/06 12:04:56 dvadura Exp $
  1361. X-- SYNOPSIS -- debugging version of malloc
  1362. X-- 
  1363. X-- DESCRIPTION
  1364. X--     malloc for debugging -- allocates via sbrk and tracks stuff, does diag
  1365. X--     dump if things appear to be screwed up.  This code is taken from a
  1366. X--    malloc package off the net.  By the time I got it the original authors
  1367. X--    name had disappeared.   This file can be used by anyone for any
  1368. X--    purpose, since it is originally from usenet, hence the missing
  1369. X--    copyright notice.
  1370. X-- 
  1371. X-- AUTHOR
  1372. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1373. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1374. X--
  1375. X-- LOG
  1376. X--     $Log:    malloc.c,v $
  1377. X * Revision 1.1  90/10/06  12:04:56  dvadura
  1378. X * dmake Release, Version 3.6
  1379. X * 
  1380. X*/
  1381. X
  1382. X#ifdef DBUG
  1383. X
  1384. X#include <signal.h>
  1385. X#include "extern.h"
  1386. X#include "alloc.h"
  1387. X#include "db.h"
  1388. X
  1389. Xextern char *sbrk();
  1390. Xextern char etext[];
  1391. Xextern char edata[];
  1392. Xextern char end[];
  1393. X
  1394. Xvoid
  1395. XMy_free( ptr, fil, line )/*
  1396. X===========================
  1397. X   A routine that check the freeing of NULL pointers. */
  1398. Xchar *ptr;
  1399. Xchar *fil;
  1400. Xint  line;
  1401. X{
  1402. X#ifdef DB_MALLOC
  1403. X   _malldstr( "free: file:" );
  1404. X   _malldstr( fil );
  1405. X   _malldstr( " line: " );
  1406. X   _dbdumpint( line );
  1407. X   _malldstr( " ::  " );
  1408. X#endif
  1409. X
  1410. X   if( ptr == NIL( char ) )
  1411. X      Fatal( "Freeing NIL pointer" );
  1412. SHAR_EOF
  1413. echo "End of part 22"
  1414. echo "File common/malloc.c is continued in part 23"
  1415. echo "23" > s2_seq_.tmp
  1416. exit 0
  1417.  
  1418.